home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * Generic parser for the "Irit" solid modeller, in binary mode. *
- * *
- * Written by: Gershon Elber Ver 0.1, Nov. 1993 *
- *****************************************************************************/
-
- #include <stdio.h>
- #include <ctype.h>
- #include <math.h>
- #include <string.h>
- #include <setjmp.h>
- #include "irit_sm.h"
- #include "iritprsr.h"
- #include "allocate.h"
- #include "attribut.h"
- #include "irit_soc.h"
-
- #define BIN_FILE_SYNC_STAMP 0x30106000
-
- static int InputGetBinSync(FILE *f);
- static VoidPtr InputGetBinBlock(FILE *f, VoidPtr Block, int Size);
- static void OutputPutBinSync(FILE *f, int Type);
- static void OutputPutBinBlock(FILE *f, VoidPtr Block, int Size);
- static void IritPrsrGetBinObjectAux(void *f, IPObjectStruct *PObjParent);
- static IPPolygonStruct *InputGetBinPolys(FILE *f, int IsPolygon);
- static CagdCrvStruct *InputGetBinCurves(FILE *f);
- static CagdSrfStruct *InputGetBinSurfaces(FILE *f);
- static MatrixType *InputGetBinMatrix(FILE *f);
- static char *InputGetBinString(FILE *f);
- static IPObjectStruct **InputGetBinOList(FILE *f, int Len);
- static IPAttributeStruct *InputGetBinAttributes(FILE *f);
- static void OutputPutBinPolys(FILE *f, IPPolygonStruct *Pl);
- static void OutputPutBinCurves(FILE *f, CagdCrvStruct *Crv);
- static void OutputPutBinSurfaces(FILE *f, CagdSrfStruct *Srf);
- static void OutputPutBinAttributes(FILE *f, IPAttributeStruct *Attrs);
-
- /*****************************************************************************
- * Routine to get a sync stamp from input stream. *
- * Returns zero if no input is available. *
- *****************************************************************************/
- static int InputGetBinSync(FILE *f)
- {
- unsigned long l;
-
- InputGetBinBlock(f, (VoidPtr) &l, sizeof(long));
-
- if ((l & 0xffffff00) == BIN_FILE_SYNC_STAMP)
- return l & 0xff;
- else
- return 0;
- }
-
- /*****************************************************************************
- * Routine to get a block of character from input stream. *
- * If input returns EOF wait until new inputs arrive (can happen if reading *
- * from a non io blocked socket). *
- *****************************************************************************/
- static VoidPtr InputGetBinBlock(FILE *f, VoidPtr Block, int Size)
- {
- int c;
- char
- *p = (char *) Block;
-
- if (Block == NULL)
- Block = IritMalloc(Size);
-
- while (Size-- > 0) {
- if (_IritPrsrReadSocket) {
- while ((c = SocClientReadCharNonBlock()) == EOF) {
- IritSleep(10);
- }
- }
- else
- c = getc(f);
-
- *p++ = c;
- }
-
- return Block;
- }
-
- /*****************************************************************************
- * Routine to put a sync stamp to output stream. *
- *****************************************************************************/
- static void OutputPutBinSync(FILE *f, int Type)
- {
- unsigned long l = (Type | BIN_FILE_SYNC_STAMP);
-
- OutputPutBinBlock(f, (VoidPtr) &l, sizeof(long));
- }
-
- /*****************************************************************************
- * Routine to put a block of character to output stream. *
- *****************************************************************************/
- static void OutputPutBinBlock(FILE *f, VoidPtr Block, int Size)
- {
- if (_IritPrsrWriteSocket) {
- SocServerWriteLine(Block, Size);
- }
- else
- fwrite(Block, Size, 1, f);
- }
-
- /*****************************************************************************
- * Routine to read one object from a given binary file, directly. *
- * Note objects may be recursively defined. *
- *****************************************************************************/
- IPObjectStruct *IritPrsrGetBinObject(void *f)
- {
- IPObjectStruct
- *PObjParent = IPAllocObject("", IP_OBJ_UNDEF, NULL);
-
- /* If the following gain control and is non zero - its from error! */
- if (setjmp(_IritPrsrLongJumpBuffer) != 0) {
- /* Error had occured (and will be reported). Return something... */
- PObjParent -> ObjType = IP_OBJ_NUMERIC;
- PObjParent -> U.R = 0.0;
- return PObjParent;
- }
-
- IritPrsrGetBinObjectAux(f, PObjParent);
-
- return IritPrsrProcessReadObject(PObjParent);
- }
-
- /*****************************************************************************
- * Routine to read one object from a given binary file, directly. *
- * Note objects may be recursively defined. *
- *****************************************************************************/
- static void IritPrsrGetBinObjectAux(void *f, IPObjectStruct *PObjParent)
- {
- int Sync = InputGetBinSync(f);
-
- InputGetBinBlock(f, (VoidPtr) PObjParent, sizeof(IPObjectStruct));
- PObjParent -> Pnext = NULL;
- PObjParent -> Count = 1;
-
- if (PObjParent -> Attrs)
- PObjParent -> Attrs = InputGetBinAttributes(f);
-
- switch (Sync) {
- case IP_OBJ_POLY:
- PObjParent -> U.Pl =
- InputGetBinPolys(f, IP_IS_POLYGON_OBJ(PObjParent));
- break;
- case IP_OBJ_NUMERIC:
- break;
- case IP_OBJ_POINT:
- break;
- case IP_OBJ_VECTOR:
- break;
- case IP_OBJ_PLANE:
- break;
- case IP_OBJ_MATRIX:
- PObjParent -> U.Mat = InputGetBinMatrix(f);
- break;
- case IP_OBJ_CURVE:
- PObjParent -> U.Crvs = InputGetBinCurves(f);
- break;
- case IP_OBJ_SURFACE:
- PObjParent -> U.Srfs = InputGetBinSurfaces(f);
- break;
- case IP_OBJ_STRING:
- PObjParent -> U.Str = InputGetBinString(f);
- break;
- case IP_OBJ_LIST_OBJ:
- PObjParent -> U.Lst.PObjList =
- InputGetBinOList(f, PObjParent -> U.Lst.ListMaxLen);
- break;
- case IP_OBJ_CTLPT:
- break;
- default:
- IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
- }
-
- if (Sync != IP_OBJ_LIST_OBJ &&
- AttrGetObjectColor(PObjParent) == IP_ATTR_NO_COLOR)
- AttrSetObjectColor(PObjParent, IP_LOAD_COLOR);
- }
-
- /*****************************************************************************
- * Routine to get a list of polys from bin input stream. *
- *****************************************************************************/
- static IPPolygonStruct *InputGetBinPolys(FILE *f, int IsPolygon)
- {
- int PSync;
- IPPolygonStruct
- *PHead = NULL,
- *PTail = NULL;
-
- while ((PSync = InputGetBinSync(f)) == IP_OBJ_AUX_POLY) {
- int VSync;
- IPPolygonStruct
- *Poly = IPAllocPolygon(0, 0, NULL, NULL);
- IPVertexStruct *Vrtx,
- *VTail = NULL;
-
- InputGetBinBlock(f, (VoidPtr) Poly, sizeof(IPPolygonStruct));
- if (Poly -> Attrs)
- Poly -> Attrs = InputGetBinAttributes(f);
-
- Poly -> PVertex = NULL;
- while ((VSync = InputGetBinSync(f)) == IP_OBJ_AUX_VERTEX) {
- Vrtx = IPAllocVertex(0, 0, NULL, NULL);
- InputGetBinBlock(f, (VoidPtr) Vrtx, sizeof(IPVertexStruct));
- if (Vrtx -> Attrs)
- Vrtx -> Attrs = InputGetBinAttributes(f);
-
- if (Poly -> PVertex) {
- VTail -> Pnext = Vrtx;
- VTail = Vrtx;
- }
- else {
- VTail = Poly -> PVertex = Vrtx;
- }
- }
- if (_IritPrsrPolyListCirc)
- VTail -> Pnext = Poly -> PVertex;
- else
- VTail -> Pnext = NULL;
- if (VSync != IP_OBJ_AUX_END)
- IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
-
- if (IsPolygon) {
- if (!IP_HAS_PLANE_POLY(Poly))
- IritPrsrUpdatePolyPlane(Poly);
-
- IritPrsrUpdateVrtxNrml(Poly, Poly -> Plane);
- }
-
- if (PHead) {
- PTail -> Pnext = Poly;
- PTail = Poly;
- }
- else {
- PHead = PTail = Poly;
- }
- }
- if (PSync != IP_OBJ_AUX_END)
- IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
-
- if (PTail)
- PTail -> Pnext = NULL;
-
- if (PHead == NULL)
- IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
-
- return PHead;
- }
-
- /*****************************************************************************
- * Routine to get a list of curves from bin input stream. *
- *****************************************************************************/
- static CagdCrvStruct *InputGetBinCurves(FILE *f)
- {
- int i, Sync, Size;
- CagdCrvStruct *Crv,
- *CHead = NULL,
- *CTail = NULL;
-
- while ((Sync = InputGetBinSync(f)) == IP_OBJ_AUX_CURVE) {
- Crv = (CagdCrvStruct *) IritMalloc(sizeof(CagdCrvStruct));
- InputGetBinBlock(f, (VoidPtr) Crv, sizeof(CagdCrvStruct));
- Size = sizeof(CagdRType) * Crv -> Length;
-
- for (i = !CAGD_IS_RATIONAL_PT(Crv -> PType);
- i <= CAGD_NUM_OF_PT_COORD(Crv -> PType);
- i++) {
- Crv -> Points[i] = (CagdRType *) IritMalloc(Size);
- InputGetBinBlock(f, (VoidPtr) (Crv -> Points[i]), Size);
- }
-
- for (i = CAGD_NUM_OF_PT_COORD(Crv -> PType) + 1;
- i <= CAGD_MAX_PT_COORD;
- i++)
- Crv -> Points[i] = NULL;
-
- if (Crv -> GType == CAGD_CBSPLINE_TYPE) {
- Size = sizeof(CagdRType) * (Crv -> Length + Crv -> Order);
- Crv -> KnotVector = (CagdRType *) IritMalloc(Size);
- InputGetBinBlock(f, (VoidPtr) (Crv -> KnotVector), Size);
- }
-
- if (CHead == NULL) {
- CHead = CTail = Crv;
- }
- else {
- CTail -> Pnext = Crv;
- CTail = Crv;
- }
- }
- if (Sync != IP_OBJ_AUX_END)
- IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
-
- if (CHead == NULL)
- IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
-
- return CHead;
- }
-
- /*****************************************************************************
- * Routine to get a list of surfaces from bin input stream. *
- *****************************************************************************/
- static CagdSrfStruct *InputGetBinSurfaces(FILE *f)
- {
- int i, Sync, Size;
- CagdSrfStruct *Srf,
- *SHead = NULL,
- *STail = NULL;
-
- while ((Sync = InputGetBinSync(f)) == IP_OBJ_AUX_SURFACE) {
- Srf = (CagdSrfStruct *) IritMalloc(sizeof(CagdSrfStruct));
- InputGetBinBlock(f, (VoidPtr) Srf, sizeof(CagdSrfStruct));
- Size = sizeof(CagdRType) * Srf -> ULength * Srf -> VLength;
-
- for (i = !CAGD_IS_RATIONAL_PT(Srf -> PType);
- i <= CAGD_NUM_OF_PT_COORD(Srf -> PType);
- i++) {
- Srf -> Points[i] = (CagdRType *) IritMalloc(Size);
- InputGetBinBlock(f, (VoidPtr) (Srf -> Points[i]), Size);
- }
-
- for (i = CAGD_NUM_OF_PT_COORD(Srf -> PType) + 1;
- i <= CAGD_MAX_PT_COORD;
- i++)
- Srf -> Points[i] = NULL;
-
- if (Srf -> GType == CAGD_SBSPLINE_TYPE) {
- Size = sizeof(CagdRType) * (Srf -> ULength + Srf -> UOrder);
- Srf -> UKnotVector = (CagdRType *) IritMalloc(Size);
- InputGetBinBlock(f, (VoidPtr) (Srf -> UKnotVector), Size);
- Size = sizeof(CagdRType) * (Srf -> VLength + Srf -> VOrder);
- Srf -> VKnotVector = (CagdRType *) IritMalloc(Size);
- InputGetBinBlock(f, (VoidPtr) (Srf -> VKnotVector), Size);
- }
-
- if (SHead == NULL) {
- SHead = STail = Srf;
- }
- else {
- STail -> Pnext = Srf;
- STail = Srf;
- }
- }
- if (Sync != IP_OBJ_AUX_END || SHead == NULL)
- IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
-
- return SHead;
- }
-
- /*****************************************************************************
- * Routine to get a matrix from bin input stream. *
- *****************************************************************************/
- static MatrixType *InputGetBinMatrix(FILE *f)
- {
- MatrixType *Mat;
-
- if (InputGetBinSync(f) != IP_OBJ_AUX_MATRIX)
- IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
- Mat = (MatrixType *) IritMalloc(sizeof(MatrixType));
- InputGetBinBlock(f, (VoidPtr) Mat, sizeof(MatrixType));
-
- return Mat;
- }
-
- /*****************************************************************************
- * Routine to get a string from bin input stream. *
- *****************************************************************************/
- static char *InputGetBinString(FILE *f)
- {
- long Len;
- char *Str;
-
- if (InputGetBinSync(f) != IP_OBJ_AUX_STRING)
- IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
- InputGetBinBlock(f, (VoidPtr) &Len, sizeof(long));
- Str = (char *) IritMalloc(Len);
- InputGetBinBlock(f, (VoidPtr) Str, Len);
- return Str;
- }
-
- /*****************************************************************************
- * Routine to get an object list from bin input stream. *
- *****************************************************************************/
- static IPObjectStruct **InputGetBinOList(FILE *f, int Len)
- {
- int i;
- struct IPObjectStruct *PTmp,
- **PObjList = (IPObjectStruct **)
- IritMalloc(Len * sizeof(IPObjectStruct *));
-
- if (InputGetBinSync(f) != IP_OBJ_AUX_OLST)
- IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
- InputGetBinBlock(f, (VoidPtr) PObjList, Len * sizeof(IPObjectStruct *));
-
- for (i = 0; i < Len && PObjList[i] != NULL; i++) {
- PTmp = IPAllocObject("", IP_OBJ_UNDEF, NULL);
- IritPrsrGetBinObjectAux(f, PTmp);
- PObjList[i] = PTmp;
- }
- if (i < Len - 1)
- PObjList[i] = NULL;
-
- return PObjList;
- }
-
- /*****************************************************************************
- * Routine to get a list of attributes from bin input stream. *
- *****************************************************************************/
- static IPAttributeStruct *InputGetBinAttributes(FILE *f)
- {
- int Sync;
- IPAttributeStruct *Attr,
- *ATail = NULL,
- *AHead = NULL;
-
- while ((Sync = InputGetBinSync(f)) == IP_OBJ_AUX_ATTR) {
- long Len;
-
- Attr = (IPAttributeStruct *) IritMalloc(sizeof(IPAttributeStruct));
- InputGetBinBlock(f, (VoidPtr) Attr, sizeof(IPAttributeStruct));
- InputGetBinBlock(f, (VoidPtr) &Len, sizeof(long));
- Attr -> Name = IritMalloc(Len);
- InputGetBinBlock(f, (VoidPtr) (Attr -> Name), Len);
- if (Attr -> Type == IP_ATTR_STR) {
- if (InputGetBinSync(f) != IP_OBJ_AUX_STRING)
- IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
- InputGetBinBlock(f, (VoidPtr) &Len, sizeof(long));
- Attr -> U.Str = IritMalloc(Len);
- InputGetBinBlock(f, (VoidPtr) (Attr -> U.Str), Len);
- }
-
- if (AHead) {
- ATail -> Pnext = Attr;
- ATail = Attr;
- }
- else {
- ATail = AHead = Attr;
- }
- }
- if (Sync != IP_OBJ_AUX_END)
- IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
-
- return AHead;
- }
-
- /*****************************************************************************
- * Routine to write one object to a given binary file, directly. *
- * Note objects may be recursively defined. *
- *****************************************************************************/
- void IritPrsrPutBinObject(void *f, IPObjectStruct *PObj)
- {
- int i;
- long Len;
- IPObjectStruct *PTmp;
-
- /* If the following gain control and is non zero - its from error! */
- if (setjmp(_IritPrsrLongJumpBuffer) != 0) {
- /* Error had occured (and will be reported). */
- return;
- }
-
- OutputPutBinSync(f, PObj -> ObjType);
- OutputPutBinBlock(f, (VoidPtr) PObj, sizeof(IPObjectStruct));
- if (PObj -> Attrs != NULL)
- OutputPutBinAttributes(f, PObj -> Attrs);
-
- switch (PObj -> ObjType) {
- case IP_OBJ_POLY:
- OutputPutBinPolys(f, PObj -> U.Pl);
- break;
- case IP_OBJ_NUMERIC:
- break;
- case IP_OBJ_POINT:
- break;
- case IP_OBJ_VECTOR:
- break;
- case IP_OBJ_PLANE:
- break;
- case IP_OBJ_MATRIX:
- OutputPutBinSync(f, IP_OBJ_AUX_MATRIX);
- OutputPutBinBlock(f, (VoidPtr) (*PObj -> U.Mat),
- sizeof(MatrixType));
- break;
- case IP_OBJ_CURVE:
- OutputPutBinCurves(f, PObj -> U.Crvs);
- break;
- case IP_OBJ_SURFACE:
- OutputPutBinSurfaces(f, PObj -> U.Srfs);
- break;
- case IP_OBJ_STRING:
- OutputPutBinSync(f, IP_OBJ_AUX_STRING);
- Len = strlen(PObj -> U.Str) + 1;
- OutputPutBinBlock(f, (VoidPtr) &Len, sizeof(long));
- OutputPutBinBlock(f, (VoidPtr) (PObj -> U.Str), Len);
- break;
- case IP_OBJ_LIST_OBJ:
- OutputPutBinSync(f, IP_OBJ_AUX_OLST);
- OutputPutBinBlock(f, (VoidPtr) PObj -> U.Lst.PObjList,
- sizeof(IPObjectStruct *) * PObj -> U.Lst.ListMaxLen);
- for (i = 0;
- i < PObj -> U.Lst.ListMaxLen &&
- (PTmp = ListObjectGet(PObj, i)) != NULL;
- i++) {
- IritPrsrPutBinObject(f, PTmp);
- }
- break;
- case IP_OBJ_CTLPT:
- break;
- default:
- IritPrsrParserAbort(IP_ERR_BIN_UNDEF_OBJ, "");
- }
- }
-
- /*****************************************************************************
- * Routine to put a list of polys to bin output stream. *
- *****************************************************************************/
- static void OutputPutBinPolys(FILE *f, IPPolygonStruct *Pl)
- {
- for (; Pl != NULL; Pl = Pl -> Pnext) {
- IPVertexStruct
- *V = Pl -> PVertex;
-
- OutputPutBinSync(f, IP_OBJ_AUX_POLY);
- OutputPutBinBlock(f, (VoidPtr) Pl, sizeof(IPPolygonStruct));
- if (Pl -> Attrs != NULL)
- OutputPutBinAttributes(f, Pl -> Attrs);
-
- do {
- OutputPutBinSync(f, IP_OBJ_AUX_VERTEX);
- OutputPutBinBlock(f, (VoidPtr) V, sizeof(IPVertexStruct));
- if (V -> Attrs != NULL)
- OutputPutBinAttributes(f, V -> Attrs);
- V = V -> Pnext;
- }
- while (V != NULL && V != Pl -> PVertex);
- OutputPutBinSync(f, IP_OBJ_AUX_END);
- }
- OutputPutBinSync(f, IP_OBJ_AUX_END);
- }
-
- /*****************************************************************************
- * Routine to put a list of curves to bin output stream. *
- *****************************************************************************/
- static void OutputPutBinCurves(FILE *f, CagdCrvStruct *Crv)
- {
- for ( ; Crv != NULL; Crv = Crv -> Pnext) {
- int i,
- Size = sizeof(CagdRType) * Crv -> Length;
-
- OutputPutBinSync(f, IP_OBJ_AUX_CURVE);
- OutputPutBinBlock(f, (VoidPtr) Crv, sizeof(CagdCrvStruct));
-
- for (i = !CAGD_IS_RATIONAL_PT(Crv -> PType);
- i <= CAGD_NUM_OF_PT_COORD(Crv -> PType);
- i++) {
- OutputPutBinBlock(f, (VoidPtr) (Crv -> Points[i]), Size);
- }
-
- if (Crv -> GType == CAGD_CBSPLINE_TYPE) {
- Size = sizeof(CagdRType) * (Crv -> Length + Crv -> Order);
- OutputPutBinBlock(f, (VoidPtr) (Crv -> KnotVector), Size);
- }
- }
- OutputPutBinSync(f, IP_OBJ_AUX_END);
- }
-
- /*****************************************************************************
- * Routine to put a list of surfaces to bin output stream. *
- *****************************************************************************/
- static void OutputPutBinSurfaces(FILE *f, CagdSrfStruct *Srf)
- {
- for ( ; Srf != NULL; Srf = Srf -> Pnext) {
- int i,
- Size = sizeof(CagdRType) * Srf -> ULength * Srf -> VLength;
-
- OutputPutBinSync(f, IP_OBJ_AUX_SURFACE);
- OutputPutBinBlock(f, (VoidPtr) Srf, sizeof(CagdSrfStruct));
-
- for (i = !CAGD_IS_RATIONAL_PT(Srf -> PType);
- i <= CAGD_NUM_OF_PT_COORD(Srf -> PType);
- i++) {
- OutputPutBinBlock(f, (VoidPtr) (Srf -> Points[i]), Size);
- }
-
- if (Srf -> GType == CAGD_SBSPLINE_TYPE) {
- Size = sizeof(CagdRType) * (Srf -> ULength + Srf -> UOrder);
- OutputPutBinBlock(f, (VoidPtr) (Srf -> UKnotVector), Size);
- Size = sizeof(CagdRType) * (Srf -> VLength + Srf -> VOrder);
- OutputPutBinBlock(f, (VoidPtr) (Srf -> VKnotVector), Size);
- }
- }
- OutputPutBinSync(f, IP_OBJ_AUX_END);
- }
-
- /*****************************************************************************
- * Routine to put a list of attributes to bin output stream. *
- *****************************************************************************/
- static void OutputPutBinAttributes(FILE *f, IPAttributeStruct *Attrs)
- {
- for ( ; Attrs != NULL; Attrs = Attrs -> Pnext) {
- if (Attrs -> Type == IP_ATTR_INT ||
- Attrs -> Type == IP_ATTR_REAL ||
- Attrs -> Type == IP_ATTR_STR) {
- long Len = strlen(Attrs -> Name) + 1;
-
- OutputPutBinSync(f, IP_OBJ_AUX_ATTR);
- OutputPutBinBlock(f, (VoidPtr) Attrs, sizeof(IPAttributeStruct));
- OutputPutBinBlock(f, (VoidPtr) &Len, sizeof(long));
- OutputPutBinBlock(f, (VoidPtr) (Attrs -> Name), Len);
-
- if (Attrs -> Type == IP_ATTR_STR) {
- Len = strlen(Attrs -> U.Str) + 1;
-
- OutputPutBinSync(f, IP_OBJ_AUX_STRING);
- OutputPutBinBlock(f, (VoidPtr) &Len, sizeof(long));
- OutputPutBinBlock(f, (VoidPtr) (Attrs -> U.Str), Len);
- }
- }
- }
- OutputPutBinSync(f, IP_OBJ_AUX_END);
- }
-